/*
 * ip_input.c
 *
 *  Created on: 2009-5-5
 *      Author: tian
 */

#include"myip.h"
#include"mytcp.h"
#include<stdio.h>
#include<time.h>

int isequal(const struct in_addr *a,const struct in_addr *b){
	int i=0;
	for(;i<4;i++){
		if(a->part[i]!=b->part[i])
			return 0;
	}
	return 1;
}

int ip_input(void * ptrpkg){
	unsigned short *pheader=ptrpkg;
	unsigned short ip_sum=0;
	//struct ip_info *pinfo=ptrpkg;
	struct iphdr *ph=ptrpkg;
	unsigned short len=0;
	struct in_addr srcaddr,desaddr;
	desaddr=ph->des;
	srcaddr=ph->src;
	struct ip_fake_hdr ifh;
	/*check out the ip package*/
	ip_sum=ip_checksum(pheader);
	
#ifdef DROPTEST
	/*for drop test*/
	static	unsigned cnt=4;
#endif

	//for test
	printf("get package from ip %s\n",inet_ntoa(ph->src));
	printf("in ip %s \n",inet_ntoa(ph->des));
	printf("ip ver:%u ip header len:%u ",ph->ip_verhl.ip_ver,ph->ip_verhl.ip_hl*2);
	printf("ip tos:%u ip len:%u\n",ph->ip_verhl.ip_tos,ph->ip_verhl.ip_len);
	printf("ip id:%u ip ttl:%u ip pro:%u ip sum:%u\n",ph->ip_id.ip_id,ph->ip_ttl,ph->ip_pro,ph->ip_sum);
	printf("ip sum in reciver:%u data_len:",ip_sum);
	unsigned short data_len=ph->ip_verhl.ip_len-ph->ip_verhl.ip_hl*2;
	printf("%u\n",data_len);
	//test end
	if(ip_sum!=0)
		return -1;
	/*check out ip version*/
	if(ph->ip_verhl.ip_ver!=4)
		return -1;
	//i do not konw if it is right
	//need test
	len=ph->ip_verhl.ip_hl*2;
	
#ifdef DROPTEST
	/*to test the high losing rate of package(for forward)*/
	if(isequal(&desaddr,&my_ip_addr)==0){
/*		srand(((unsigned)time(NULL));
		if((rand()%5)<2)*/
		cnt = cnt - 1;
		if (cnt == 0){
			cnt = 3;
			printf("Forward Dropped!\n");
			return -1;
		}
	}
#endif

	/*decide whether forward package*/
	if(isequal(&desaddr,&my_ip_addr)==0){
		if(ph->ip_ttl>0)
			ip_forward(ptrpkg);
			return 0;
	}
	/*upload to tcp layer*/
	/*create ip fake header*/
	ifh.des=desaddr;
	ifh.src=srcaddr;
	ifh.mbz=0;
	ifh.pro=ph->ip_pro;
	/*i do not konw if it is in bytes/2*/
	ifh.tcp_l=(ph->ip_verhl.ip_len-len);
	//check protocol
	if(ph->ip_pro==PROTOCOL_TCP)
		tcp_input(&ifh,ptrpkg+len,NULL,event_null);
	else{
		fprintf(stderr,"not a tcp package,why?\n");
	}
	return 0;
}
